/*
 * Copyright (c) 2013, marco.tamburelli@gmail.com
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met: 
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.omorphdb.core.value;

import static org.omorphdb.core.value.ValueConstants._ARRAY;
import static org.omorphdb.core.value.ValueConstants._BOOLEAN;
import static org.omorphdb.core.value.ValueConstants._BYTE;
import static org.omorphdb.core.value.ValueConstants._CHAR;
import static org.omorphdb.core.value.ValueConstants._DATE;
import static org.omorphdb.core.value.ValueConstants._DOCUMENT;
import static org.omorphdb.core.value.ValueConstants._DOUBLE;
import static org.omorphdb.core.value.ValueConstants._FLOAT;
import static org.omorphdb.core.value.ValueConstants._INT;
import static org.omorphdb.core.value.ValueConstants._LONG;
import static org.omorphdb.core.value.ValueConstants._SHORT;
import static org.omorphdb.core.value.ValueConstants._STRING;

import java.util.Date;

import org.omorphdb.core.storage.document.Document;

/**
 * Set of types used for values of document attributes.
 * 
 * @author Marco Tamburelli
 */
public enum ValueType
{
	BOOLEAN
	{
		@Override
		public byte getByteType()
		{
			return _BOOLEAN;
		}

		@Override
		public Class<?> getJavaType()
		{
			return boolean.class;
		}
	},
	BYTE
	{
		@Override
		public byte getByteType()
		{
			return _BYTE;
		}

		@Override
		public Class<?> getJavaType()
		{
			return byte.class;
		}
	},
	CHAR
	{
		@Override
		public byte getByteType()
		{
			return _CHAR;
		}

		@Override
		public Class<?> getJavaType()
		{
			return char.class;
		}
	},
	SHORT
	{
		@Override
		public byte getByteType()
		{
			return _SHORT;
		}

		@Override
		public Class<?> getJavaType()
		{
			return short.class;
		}
	},
	INT
	{
		@Override
		public byte getByteType()
		{
			return _INT;
		}

		@Override
		public Class<?> getJavaType()
		{
			return int.class;
		}
	},
	LONG
	{
		@Override
		public byte getByteType()
		{
			return _LONG;
		}

		@Override
		public Class<?> getJavaType()
		{
			return long.class;
		}
	},
	FLOAT
	{
		@Override
		public byte getByteType()
		{
			return _FLOAT;
		}

		@Override
		public Class<?> getJavaType()
		{
			return float.class;
		}
	},
	DOUBLE
	{
		@Override
		public byte getByteType()
		{
			return _DOUBLE;
		}

		@Override
		public Class<?> getJavaType()
		{
			return double.class;
		}
	},
	STRING
	{
		@Override
		public byte getByteType()
		{
			return _STRING;
		}

		@Override
		public Class<?> getJavaType()
		{
			return String.class;
		}
	},
	DATE
	{
		@Override
		public byte getByteType()
		{
			return _DATE;
		}

		@Override
		public Class<?> getJavaType()
		{
			return Date.class;
		}
	},
	ARRAY
	{
		@Override
		public byte getByteType()
		{
			return _ARRAY;
		}

		@Override
		public Class<?> getJavaType()
		{
			return Object[].class;
		}
	},
	DOCUMENT
	{
		@Override
		public byte getByteType()
		{
			return _DOCUMENT;
		}

		@Override
		public Class<?> getJavaType()
		{
			return Document.class;
		}
	};

	/**
	 * Returns the byte representation of this type.
	 * 
	 * @return
	 */
	public abstract byte getByteType();

	/**
	 * Returns the java type that better represents this type.
	 * 
	 * @return
	 */
	public abstract Class<?> getJavaType();

	/**
	 * Translates a byte type representation to a {@link ValueType}.
	 * 
	 * @param type
	 * @return
	 */
	public static ValueType getValueType(byte type)
	{
		switch (type)
		{
		case _BOOLEAN:
			return ValueType.BOOLEAN;

		case _BYTE:
			return ValueType.BYTE;

		case _CHAR:
			return ValueType.CHAR;

		case _SHORT:
			return ValueType.SHORT;

		case _INT:
			return ValueType.INT;

		case _LONG:
			return ValueType.LONG;

		case _FLOAT:
			return ValueType.FLOAT;

		case _DOUBLE:
			return ValueType.DOUBLE;

		case _STRING:
			return ValueType.STRING;

		case _DATE:
			return ValueType.DATE;

		case _DOCUMENT:
			return ValueType.DOCUMENT;

		case _ARRAY:
			return ValueType.ARRAY;

		default:
			return null;
		}
	}
}
